#pragma once
#include<vector>




namespace lin
{
	template<class T>
	struct less
	{
		bool operator()(const T& left, const T& right)
		{
			return left < right;
		}
	};
	template<class T>
	struct greator
	{
		bool operator()(const T& left, const T& right)
		{
			return left > right;
		}
	};

	//template<class T, class Con = vector<T>, class Compare = less<T> >
	template<class T, class Con = vector<T>, class Compare = greator<T> >
	class priority_queue
	{
	public:
		priority_queue()
		{}

		template<class Iterator>
		priority_queue(Iterator left, Iterator right)
			:_con(left, right)
		{
			int count = _con.size();
			int root = (count - 1) * 2;
			for (; root >= 0; root--)
			{
				AdjustDown(root);
			}
		}

		void push(const T& x)
		{
			_con.push_back(x);
			AdjustUP(_con.size() - 1);
		}
		void pop()
		{
			if (empty())
				return;
			swap(_con.front(), _con.back());
			_con.pop_back();
			AdjustDown(0);
		}
		bool empty() const
		{
			return _con.empty();
		}
		size_t size() const
		{
			return _con.size();
		}
		const T& top() const
		{
			return _con.front();
		}
	private:
		void AdjustUP(int child)
		{
			size_t parent = (child-1)/2;
			while (child>0)
			{
				if (com(_con[child] , _con[parent]))
				{
					swap(_con[child], _con[parent]);
					child = parent;
					parent = (child - 1) / 2;
				}
				else
					return;
			}
		}
		void AdjustDown(int parent)
		{
			size_t child = parent * 2 + 1;
			while (child<_con.size())
			{
				if (child+1<_con.size()&&com(_con[child+1] , _con[child]))
				{
					child += 1;
				}
				if (com(_con[child] , _con[parent]))
				{
					swap(_con[child], _con[parent]);
					parent = child;
					child = parent * 2 + 1;
				}
				else
					return;
			}
		}
	private:
		Con _con;
		Compare com;
	};

}